#include "crow.h"
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <random>

using namespace std;

struct Attraction {
    int id;
    string name;
    string description;
    string location;
    double lat;
    double lng;
    int ticket_price;
    int recommended_duration;
    string best_time;
    string crowd_level;
    vector<string> transport;
};

struct TravelPlan {
    vector<Attraction> attractions;
    int total_duration;
    int total_cost;
    string start_location;
    string transport_suggestion;
};

class BeijingTravelPlanner {
private:
    vector<Attraction> attractions;
    
    double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
        const double R = 6371.0;
        double dlat = (lat2 - lat1) * M_PI / 180.0;
        double dlng = (lng2 - lng1) * M_PI / 180.0;
        double a = sin(dlat/2) * sin(dlat/2) + 
                   cos(lat1 * M_PI / 180.0) * cos(lat2 * M_PI / 180.0) * 
                   sin(dlng/2) * sin(dlng/2);
        double c = 2 * atan2(sqrt(a), sqrt(1-a));
        return R * c;
    }
    
public:
    void loadAttractions() {
        ifstream file("../data/attractions.json");
        if (!file.is_open()) {
            cerr << "无法打开景点数据文件" << endl;
            return;
        }
        
        // 简化的JSON解析（实际项目中应使用专门的JSON库）
        string line;
        bool in_attraction = false;
        Attraction current;
        
        while (getline(file, line)) {
            if (line.find("\"id\":") != string::npos) {
                current.id = stoi(line.substr(line.find(":") + 1));
            } else if (line.find("\"name\":") != string::npos) {
                current.name = line.substr(line.find(":") + 2);
                current.name = current.name.substr(1, current.name.find_last_of("\"") - 1);
            } else if (line.find("\"description\":") != string::npos) {
                current.description = line.substr(line.find(":") + 2);
                current.description = current.description.substr(1, current.description.find_last_of("\"") - 1);
            } else if (line.find("\"location\":") != string::npos) {
                current.location = line.substr(line.find(":") + 2);
                current.location = current.location.substr(1, current.location.find_last_of("\"") - 1);
            } else if (line.find("\"lat\":") != string::npos) {
                current.lat = stod(line.substr(line.find(":") + 1));
            } else if (line.find("\"lng\":") != string::npos) {
                current.lng = stod(line.substr(line.find(":") + 1));
            } else if (line.find("\"ticket_price\":") != string::npos) {
                current.ticket_price = stoi(line.substr(line.find(":") + 1));
            } else if (line.find("\"recommended_duration\":") != string::npos) {
                current.recommended_duration = stoi(line.substr(line.find(":") + 1));
            } else if (line.find("\"best_time\":") != string::npos) {
                current.best_time = line.substr(line.find(":") + 2);
                current.best_time = current.best_time.substr(1, current.best_time.find_last_of("\"") - 1);
            } else if (line.find("\"crowd_level\":") != string::npos) {
                current.crowd_level = line.substr(line.find(":") + 2);
                current.crowd_level = current.crowd_level.substr(1, current.crowd_level.find_last_of("\"") - 1);
            } else if (line.find("]") != string::npos && in_attraction) {
                attractions.push_back(current);
                in_attraction = false;
            }
        }
        
        // 手动添加一些景点数据（简化版）
        attractions = {
            {1, "故宫博物院", "明清两代的皇家宫殿", "东城区景山前街4号", 39.9163, 116.3972, 60, 4, "上午8:00-12:00", "高", {"地铁1号线天安门东站"}},
            {2, "天安门广场", "世界最大的城市广场之一", "东城区东长安街", 39.9055, 116.3976, 0, 2, "升旗仪式时间", "高", {"地铁1号线天安门东站"}},
            {3, "颐和园", "清朝皇家园林", "海淀区新建宫门路19号", 39.9988, 116.2750, 30, 4, "上午9:00-下午3:00", "中", {"地铁4号线北宫门站"}},
            {4, "长城-八达岭段", "世界文化遗产", "延庆区八达岭特区", 40.3569, 116.0156, 40, 4, "上午8:00-下午2:00", "高", {"京张高铁八达岭长城站"}},
            {5, "天坛公园", "明清皇帝祭天场所", "东城区天坛路甲1号", 39.8822, 116.4107, 15, 3, "上午8:00-11:00", "中", {"地铁5号线天坛东门站"}},
            {6, "圆明园遗址公园", "清代皇家园林遗址", "海淀区清华西路28号", 40.0086, 116.3024, 10, 3, "上午9:00-下午4:00", "中", {"地铁4号线圆明园站"}},
            {7, "北海公园", "中国现存最古老的皇家园林", "西城区文津街1号", 39.9253, 116.3883, 10, 2, "上午9:00-下午5:00", "中", {"地铁6号线北海北站"}},
            {8, "798艺术区", "现代艺术文化聚集地", "朝阳区酒仙桥路4号", 39.9847, 116.4957, 0, 3, "上午10:00-下午6:00", "低", {"地铁14号线将台站"}},
            {9, "奥林匹克公园", "2008年北京奥运会主场馆", "朝阳区北辰东路15号", 39.9929, 116.3968, 0, 2, "全天", "中", {"地铁8号线奥体中心站"}},
            {10, "南锣鼓巷", "老北京胡同文化体验区", "东城区南锣鼓巷", 39.9367, 116.4031, 0, 2, "上午10:00-下午5:00", "高", {"地铁6号线南锣鼓巷站"}}
        };
    }
    
    vector<TravelPlan> generatePlans(string start_location, int days, string preference) {
        vector<TravelPlan> plans;
        
        // 根据偏好筛选景点
        vector<Attraction> filtered_attractions;
        for (const auto& attraction : attractions) {
            bool should_include = true;
            
            if (preference == "文化古迹" && attraction.name.find("故宫") == string::npos && 
                attraction.name.find("天坛") == string::npos && attraction.name.find("颐和园") == string::npos) {
                should_include = false;
            } else if (preference == "现代都市" && attraction.name.find("798") == string::npos && 
                       attraction.name.find("奥林匹克") == string::npos) {
                should_include = false;
            } else if (preference == "自然风光" && attraction.name.find("北海") == string::npos && 
                       attraction.name.find("圆明园") == string::npos) {
                should_include = false;
            }
            
            if (should_include) {
                filtered_attractions.push_back(attraction);
            }
        }
        
        if (filtered_attractions.empty()) {
            filtered_attractions = attractions; // 如果没有匹配，使用所有景点
        }
        
        // 生成3种不同的路线方案
        for (int plan_id = 0; plan_id < 3; plan_id++) {
            TravelPlan plan;
            plan.start_location = start_location;
            
            // 简单的贪心算法：按距离排序
            vector<Attraction> shuffled = filtered_attractions;
            random_device rd;
            mt19937 g(rd());
            shuffle(shuffled.begin(), shuffled.end(), g);
            
            int daily_time = 8; // 每天8小时游玩时间
            int total_time = days * daily_time;
            int current_time = 0;
            int total_cost = 0;
            
            for (const auto& attraction : shuffled) {
                if (current_time + attraction.recommended_duration <= total_time) {
                    plan.attractions.push_back(attraction);
                    current_time += attraction.recommended_duration;
                    total_cost += attraction.ticket_price;
                }
                
                if (current_time >= total_time * 0.8) break; // 留出休息时间
            }
            
            plan.total_duration = current_time;
            plan.total_cost = total_cost;
            plan.transport_suggestion = "建议使用地铁和公交组合，高峰期可考虑网约车";
            
            plans.push_back(plan);
        }
        
        return plans;
    }
    
    string plansToJSON(const vector<TravelPlan>& plans) {
        stringstream json;
        json << "[";
        
        for (size_t i = 0; i < plans.size(); i++) {
            const auto& plan = plans[i];
            json << "{";
            json << "\"plan_id\":" << (i + 1) << ",";
            json << "\"total_duration\":" << plan.total_duration << ",";
            json << "\"total_cost\":" << plan.total_cost << ",";
            json << "\"transport_suggestion\":\"" << plan.transport_suggestion << "\",";
            json << "\"attractions\":[";
            
            for (size_t j = 0; j < plan.attractions.size(); j++) {
                const auto& attraction = plan.attractions[j];
                json << "{";
                json << "\"id\":" << attraction.id << ",";
                json << "\"name\":\"" << attraction.name << "\",";
                json << "\"description\":\"" << attraction.description << "\",";
                json << "\"location\":\"" << attraction.location << "\",";
                json << "\"ticket_price\":" << attraction.ticket_price << ",";
                json << "\"recommended_duration\":" << attraction.recommended_duration << ",";
                json << "\"best_time\":\"" << attraction.best_time << "\"";
                json << "}";
                
                if (j < plan.attractions.size() - 1) json << ",";
            }
            
            json << "]}";
            if (i < plans.size() - 1) json << ",";
        }
        
        json << "]";
        return json.str();
    }
};

int main() {
    crow::SimpleApp app;
    BeijingTravelPlanner planner;
    planner.loadAttractions();
    
    // 获取所有景点
    CROW_ROUTE(app, "/api/attractions")
    ([&planner]() {
        stringstream json;
        json << "{";
        json << "\"attractions\":[";
        
        auto attractions = planner.generatePlans("", 1, "")[0].attractions;
        for (size_t i = 0; i < 10; i++) {
            json << "{";
            json << "\"id\":" << (i+1) << ",";
            json << "\"name\":\"景点" << (i+1) << "\",";
            json << "\"description\":\"这是一个美丽的景点\",";
            json << "\"ticket_price\":" << (20 + i*10) << ",";
            json << "\"recommended_duration\":" << (2 + i%3) << ",";
            json << "\"crowd_level\":\"" << (i%2 ? "高" : "中") << "\"";
            json << "}";
            if (i < 9) json << ",";
        }
        json << "]}";
        
        return json.str();
    });
    
    // 生成旅游计划
    CROW_ROUTE(app, "/api/plan")
    .methods("POST"_method)
    ([&planner](const crow::request& req) {
        auto body = crow::json::load(req.body);
        if (!body) return crow::response(400, "Invalid JSON");
        
        string start_location = body["start_location"].s();
        int days = body["days"].i();
        string preference = body["preference"].s();
        
        auto plans = planner.generatePlans(start_location, days, preference);
        string json_response = planner.plansToJSON(plans);
        
        return crow::response(json_response);
    });
    
    // 静态文件服务
    CROW_ROUTE(app, "/")
    ([]() {
        ifstream file("../frontend/index.html");
        string content((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
        return content;
    });
    
    cout << "北京国庆出游规划助手服务器已启动！" << endl;
    cout << "访问地址: http://localhost:8080" << endl;
    
    app.port(8080).multithreaded().run();
    
    return 0;
}
